perm filename PPROC2.OLD[PNT,HE]3 blob
sn#496211 filedate 1980-02-08 generic text, type C, neo UTF8
COMMENT ⊗ VALID 00010 PAGES
C REC PAGE DESCRIPTION
C00001 00001
C00002 00002 ENTRY
C00005 00003 ! cmonproc
C00014 00004 ! arm interactions: read_pos,readarm,frasg,arm_check
C00016 00005 ! arm interactions: fconstructproc
C00020 00006 ! arm motions: movepcode,alongproc,axmovproc, pbyproc,ptoproc
C00032 00007 ! drivecode,opclcode,jtmove,driveproc
C00035 00008 ! centerproc,stopproc,retryproc
C00037 00009 ! opening, opclproc,closeproc
C00039 00010 ! onproc
C00044 ENDMK
C⊗;
ENTRY;
BEGIN "PPROC2"
DEFINE $$PRGID=TRUE;
DEFINE $PPROC2=TRUE;
DEFINE $ALTER_EGO=TRUE;
REQUIRE "HEADER.SAI" SOURCE_FILE;
SIMPLE INTEGER PROCEDURE UPLEVEL(INTEGER OFFSET);
BEGIN ! eliminate this when moving to PARSE.SAI ;
INTEGER I;
I ← (OFFSET +1) LSH -8 ; ! this gives the level ;
I ← (I+1) LSH 8 ; ! this gives the next level ;
RETURN(I);
END;
RECORD_CLASS CLAUSE(RPTR(EXPR$)HEADER,HEAD,TAIL;
INTEGER TYPE,VALUE;
BOOLEAN WITH;REAL FVALUE);
DEFINE NEITHER_TYPE=0,
EQUALITY_TYPE=1,
RELATIONAL_TYPE=2;
DEFINE FORCE_COND=3; ! for forces and torques;
DEFINE TORQUE_COND=4;
DEFINE DURATION_COND=5,
APPROACH_COND=6,
DEPARTURE_COND=7,
SPEED_FACTOR_COND=8,
FORCE_FRAME_COND=9,
NULLING_COND=10,
NO_NULLING_COND=11,
STIFFNESS_COND=12,
DRIVER_TURNS_COND=13,
RTMOVE_COND=14,
WOBBLE_COND=15,
STOP_WAIT_TIME_COND=16,
ANGULAR_VELOCITY_COND=17,
FAILURE_COND=18,
EXPRESSION_COND=19,
EVENT_COND=20,
SETBASE_COND=21;
! cmonproc;
RECURSIVE PROCEDURE FORCECMON(RPTR(CLAUSE)CL;INTEGER BITOFFSET; BOOLEAN ABSOLUTE(FALSE));
BEGIN
INTEGER V; BOOLEAN GE; RPTR(EXPR$)EXP,ACTION;
INTEGER I,IPC;
INTEGER BITS,DEVBITS,TMPOFF;
RPTR(SYMBOL)C;
DEVBITS←BITOFFSET LAND '17;
WORD_READ("("); GTOKEN;
IF EQU(TOKEN,"XHAT") THEN BITS←BITOFFSET
ELSE IF EQU(TOKEN,"YHAT") THEN BITS←BITOFFSET+'1000
ELSE IF EQU(TOKEN,"ZHAT") THEN BITS←BITOFFSET+'2000
ELSE ERROR("FORCECM: only principal directions allowed");
WORD_READ(")");
IF ABSOLUTE THEN BEGIN WORD_READ("|"); BITS←BITS + '20000; END;
GTOKEN;
IF TOKEN="≥" OR TOKEN =">" THEN BITS←BITS+'100000
ELSE IF TOKEN="≤" OR TOKEN="<" THEN BITS←BITS
ELSE ERROR("FORCECM: need ≥ or < here");
EXP←$$GTANYEXP("FORCECM",#SC);
GTOKEN;
IF EQU(TOKEN,"IN") THEN
BEGIN
GTOKEN;
IF EQU(TOKEN,"HAND") THEN BITS←BITS
ELSE IF EQU(TOKEN,"STATION") THEN BEGIN BITS←BITS+'400; DEVBITS←DEVBITS+'400; END
ELSE ERROR("FORCECM: can only specify in HAND or STATION");
WORD_READ("DO");
END
ELSE BEGIN IF NOT EQU(TOKEN,"DO") THEN ERROR("FORCECM: Need DO here");
BITS←BITS+'400; DEVBITS←DEVBITS+'400; ! default is station;
END;
TMPOFF←$TMPOFF; $TMPOFF←UPLEVEL($TMPOFF);
PARSE;
ACTION←$$PCODE;
$TMPOFF←TMPOFF;
$FFRCPCODE(CLAUSE:HEADER[CL],CLAUSE:HEAD[CL],CLAUSE:TAIL[CL],
EXP,ACTION,BITS,DEVBITS,$TMPOFF);
$TMPOFF←$TMPOFF+1;
GTOKEN(FALSE);
END;
RECURSIVE PROCEDURE DURCMON(RPTR(CLAUSE)CL);
BEGIN
INTEGER TMPOFF; RPTR(EXPR$)EXP,ACTION;
GTOKEN;
IF TOKEN≠">" AND TOKEN≠"≥" THEN ERROR("DURATION CMON: Need > or ≥ here");
EXP←$$GTANYEXP("DURATION CMON",#SC);
WORD_READ("DO");
TMPOFF←$TMPOFF; $TMPOFF←UPLEVEL($TMPOFF);
PARSE;
ACTION←$$PCODE;
$TMPOFF←TMPOFF;
$DURCPCODE(CLAUSE:HEADER[CL],CLAUSE:HEAD[CL],CLAUSE:TAIL[CL],EXP,ACTION,$TMPOFF);
$TMPOFF←$TMPOFF+1;
GTOKEN(FALSE);
END;
RECURSIVE PROCEDURE EXPCMON(RPTR(CLAUSE)CL);
BEGIN
RPTR(EXPR$)EXP,ACTION; INTEGER TMPOFF;
STOKEN←TRUE;
EXP←$$GTANYEXP("EXPRESSION CMON",#SC);
WORD_READ("DO");
TMPOFF←$TMPOFF; $TMPOFF←UPLEVEL($TMPOFF);
PARSE;
ACTION←$$PCODE;
$TMPOFF←TMPOFF;
$EXPCPCODE(CLAUSE:HEADER[CL],CLAUSE:HEAD[CL],CLAUSE:TAIL[CL],EXP,ACTION,$TMPOFF);
$TMPOFF←$TMPOFF+1;
GTOKEN(FALSE);
END;
RECURSIVE PROCEDURE EVCMON(RPTR(CLAUSE)CL);
BEGIN
RPTR(EXPR$)EXP,ACTION; INTEGER TMPOFF; RPTR(SYMBOL)SYM;
STOKEN←TRUE;
EXP←$$GTIDREF(#EV,SYM,"EVENT CMON");
WORD_READ("DO");
TMPOFF←$TMPOFF;$TMPOFF←UPLEVEL($TMPOFF);
PARSE;
ACTION←$$PCODE;
$TMPOFF←TMPOFF;
$EVCPCODE(CLAUSE:HEADER[CL],CLAUSE:HEAD[CL],CLAUSE:TAIL[CL],EXP,ACTION,$TMPOFF);
$TMPOFF←$TMPOFF+1;
GTOKEN(FALSE);
END;
RECURSIVE PROCEDURE CMONPROC(RPTR(CLAUSE)CL;INTEGER BITS);
BEGIN
INTEGER NBITS; BOOLEAN SAVERRORCMON;
$COMPILE←$COMPILE+1;
GTOKEN;
SAVERRORCMON←$ERRCMON; $ERRCMON←FALSE; $ERRLEVEL←$LEVEL;
IF TOKEN="|" THEN
BEGIN
GTOKEN;
IF EQU(TOKEN,"FORCE") THEN FORCECMON(CL,BITS,TRUE)
ELSE IF EQU(TOKEN,"TORQUE") THEN FORCECMON(CL,BITS+'3000,TRUE);
END
ELSE
IF EQU(TOKEN,"FORCE") THEN FORCECMON(CL,BITS)
ELSE IF EQU(TOKEN,"TORQUE") THEN FORCECMON(CL,BITS+'3000)
ELSE IF EQU(TOKEN,"DURATION") THEN DURCMON(CL)
ELSE IF EQU(TOKEN,"ERROR") THEN
BEGIN
$ERRCMON←TRUE;
CLAUSE:WITH[CL]←TRUE; ! actually a WITH ;
WORD_READ("=");
CLAUSE:FVALUE[CL]←$GTREAL("ERROR condition monitor");
CLAUSE:TYPE[CL]←FAILURE_COND;
WORD_READ("DO");
CLAUSE:TAIL[CL]←PARSE;
GTOKEN(FALSE);
END
ELSE IF (#TOKEN=ID_TYPE) AND (SYMBOL:TYPE[TOKENPTR]=#EV) THEN EVCMON(CL)
ELSE EXPCMON(CL);
$ERRCMON←SAVERRORCMON; $ERRLEVEL←$LEVEL;
$COMPILE←$COMPILE-1;
END;
RECURSIVE PROCEDURE WITHPROC(RPTR(CLAUSE)CL);
BEGIN
$COMPILE←$COMPILE+1;
CLAUSE:WITH[CL]←TRUE;
GTOKEN;
IF EQU(TOKEN,"WRIST") THEN
BEGIN BOOLEAN NOBASE;
GTOKEN; IF EQU(TOKEN,"NOT") THEN NOBASE←TRUE ELSE BEGIN NOBASE←FALSE;
GTOKEN; END;
IF EQU(TOKEN,"ZEROED") THEN
IF ¬NOBASE THEN CLAUSE:HEAD[CL]←$SETBASEPCODE;
CLAUSE:TYPE[CL]←SETBASE_COND;
END
ELSE IF EQU(TOKEN,"STIFFNESS") THEN
BEGIN
WORD_READ("=");
SETSTIFFPROC;
CLAUSE:HEAD[CL]←$$PCODE;
CLAUSE:TYPE[CL]←STIFFNESS_COND;
END
ELSE IF EQU(TOKEN,"WOBBLE") THEN
BEGIN
WORD_READ("=");
CLAUSE:FVALUE[CL]←$GTREAL("WOBBLE command");
CLAUSE:TYPE[CL]←WOBBLE_COND;
END
ELSE IF EQU(TOKEN,"DURATION") THEN
BEGIN
WORD_READ("=");
CLAUSE:FVALUE[CL]←$GTREAL("DURATION command");
CLAUSE:TYPE[CL]←DURATION_COND;
END
ELSE IF EQU(TOKEN,"FORCE") THEN
ERROR("WITH: cannot currently handle "&TOKEN)
ELSE IF EQU(TOKEN,"NULLING") THEN
CLAUSE:TYPE[CL]←NULLING_COND
ELSE IF EQU(TOKEN,"NO_NULLING") THEN
CLAUSE:TYPE[CL]←NO_NULLING_COND
ELSE IF EQU(TOKEN,"SPEED_FACTOR") THEN
BEGIN
WORD_READ("=");
CLAUSE:FVALUE[CL]←$GTREAL("SPEED_FACTOR command");
CLAUSE:TYPE[CL]←SPEED_FACTOR_COND;
END
ELSE IF EQU(TOKEN,"ARRIVAL") THEN
BEGIN
WORD_READ("=");
CLAUSE:HEAD[CL]←$$GTEXPR;
CLAUSE:TYPE[CL]←APPROACH_COND;
END
ELSE IF EQU(TOKEN,"DEPARTURE") THEN
BEGIN
WORD_READ("=");
CLAUSE:HEAD[CL]←$$GTEXPR;
CLAUSE:TYPE[CL]←DEPARTURE_COND;
END
ELSE ERROR("WITH: cannot currently handle "&TOKEN);
GTOKEN(FALSE);
$COMPILE←$COMPILE-1;
END;
! arm interactions: read_pos,readarm,frasg,arm_check;
IFC FALSE THENC
! assigns the value of pos(pointer or arm) to the frame fra. If direct
is indicated uses it to set the rotation part;
! returns the pointer to the input device pos (arm or pointer);
RPTR (FRAME) PROCEDURE INPT_DEV(REFERENCE STRING POS);
BEGIN
RPTR(FRAME) FROM;
IF EQU(POS,"BARM")
THEN RETURN(F_BARM)
ELSE IF EQU(POS,"YARM")
THEN RETURN(F_YARM)
ELSE BEGIN
FROM←BELONGS(POS,#FR);
WHILE FROM≠F_BARM AND FROM≠F_YARM
DO BEGIN
PRINT("reading on arm required");
POS←RECOVER(POS);
FROM←BELONGS (POS,#FR);
END;
RETURN(FROM);
END;
END;
! reads the position of the arm from, or of the arm with pointer;
PROCEDURE READ_DEV(RPTR(FRAME) FROM);
print("dummy call to get value of the frame");
! reads the position of the device pos (arm or pointer);
PROCEDURE INPT(REFERENCE STRING POS);
BEGIN
RPTR(FRAME)FROM;
FROM←INPT_DEV(POS);
READ_DEV(FROM);
END;
ENDC
! arm interactions: fconstructproc;
! reads an axis name and returns its number:
xhat=0,yhat=1,zhat=2;
IFC FALSE THENC
INTEGER PROCEDURE INPT_AXIS(REFERENCE STRING AXIS);
WHILE TRUE DO
BEGIN
AXIS←RECOVER(AXIS);
IF EQU(AXIS[2 TO ∞],"HAT") THEN RETURN(AXIS - "X")
ELSE PRINT("--→ XHAT or YHAT or ZHAT required ←--",
CRLF,"Try again ");
END;
RPTR(TRANS) ARRAY T_CSTR[1:3];
! used by CONSTRUCT instruction;
! performs a construct instruction, without arguments;
PROCEDURE FCONSTRUCTPROC;
BEGIN
RPTR(FRAME) ELF;RPTR(TRANS)XFE;INTEGER I;
RPTR(FRAME) FROM;STRING POS,ANSWER,FIRST;
RPTR(VECTOR) V1,V2,V3;
PRELOAD_WITH
"move arm to the origin of the frame"&CRLF,
"move arm to the axis ",
"move arm to the plane ";
OWN STRING ARRAY INFORM[1:3];
STRING AXIS;INTEGER F_AXIS,S_AXIS;
$ALLOW←$ALLOW+1;
GTOKEN;
IF #TOKEN≠UNDECLARED_TYPE THEN ERROR("Need undeclared token for FCONSTRUCT")
ELSE FIRST←TOKEN;
AXIS←NULL;
IF F_POINTER=NULL_RECORD
THEN PRINT("pointer is not defined cannot be used",CRLF)
ELSE POS←"POINTER";
PRINT("three positions are required",CRLF);
FOR I←1 STEP 1 UNTIL 3 DO
BEGIN
! determination of the input device required;
PRINT("position ",I," read on ");
POS←RECOVER(POS);
FROM←INPT_DEV(POS); ! checks the input device;
! determination of the positions for reading;
PRINT(INFORM[I]);
IF I=2
THEN F_AXIS←INPT_AXIS(AXIS)
ELSE IF I=3
THEN BEGIN
PRINT(AXIS," - ");
AXIS←NULL;
S_AXIS←INPT_AXIS(AXIS);
IF S_AXIS=F_AXIS THEN ERROR("instruction not executed");
END;
! reading of the arm position;
PRINT("type <cr> when the arm is at the desired position");
ANSWER←INCHRW;
IF ANSWER=CR
THEN ANSWER←INCHRW
ELSE ERROR("instruction not executed");
READ_DEV(FROM); ! raads the appropriate arm pos.;
T_CSTR[I]←ABSLOC(FROM);
END;
! extraction of translation part;
V1←TPOS(T_CSTR[1]);
V2←TPOS(T_CSTR[2]);
V3←TPOS(T_CSTR[3]);
XFE←VVVTR(V1,V2,V3,F_AXIS,S_AXIS);
ELF←FR_INSERT(FIRST); ! inserts the new frame;
ABSSET(ELF,XFE); ! sets the new value;
$ALLOW←$ALLOW-1;
IFC #DISPL THENC UPDATE;ENDC
END;
ENDC
! arm motions: movepcode,alongproc,axmovproc, pbyproc,ptoproc
moveproc, parkingproc;
RECURSIVE RPTR(EXPR$)PROCEDURE FULLMOVE(RPTR(CLAUSE)ARRAY CLAUSES;
INTEGER #CLAUSES; RPTR(EXPR$)MOVEDEC,DESTCOMP,MOVECODE,MOVEKIL);
BEGIN RPTR(RSTACK)HR,H,T;
RPTR(EXPR$)HHR,HH,TT;
RPTR(CLAUSE)FAILURE_CLAUSE;
INTEGER I,#NEWVAR;
HR←NEW_RSTACK(#CLAUSES);
H←NEW_RSTACK(#CLAUSES);
T←NEW_RSTACK(#CLAUSES);
#NEWVAR←0;
FOR I←1 STEP 1 UNTIL #CLAUSES DO
IF CLAUSE:WITH[CLAUSES[I]] THEN
CASE CLAUSE:TYPE[CLAUSES[I]] OF
BEGIN
[SETBASE_COND]
[STIFFNESS_COND] RPUSH(HR,CLAUSE:HEAD[CLAUSES[I]]);
[NO_NULLING_COND]
EXPR$:BODY[MOVECODE][5]←EXPR$:BODY[MOVECODE][5] LAND 1;
[NULLING_COND]
EXPR$:BODY[MOVECODE][5]←EXPR$:BODY[MOVECODE][5];
[DURATION_COND]
EXPR$:BODY[MOVECODE][7]←CLAUSE:FVALUE[CLAUSES[I]]*1000;
[SPEED_FACTOR_COND]
EXPR$:BODY[MOVECODE][7]←-CLAUSE:FVALUE[CLAUSES[I]]*1000;
[FAILURE_COND]
BEGIN
INTEGER J;
J←EXPR$:#BODY[MOVECODE];
EXPR$:BODY[MOVECODE][J-2]←CLAUSE:FVALUE[CLAUSES[I]];
FAILURE_CLAUSE←CLAUSES[I];
EXPR$:BODY[MOVECODE][J-1]←
5+EXPR$:#BODY[CLAUSE:TAIL[FAILURE_CLAUSE]];
END;
ELSE
END
ELSE
BEGIN RPUSH(HR,CLAUSE:HEADER[CLAUSES[I]]);
RPUSH(H,CLAUSE:HEAD[CLAUSES[I]]);
RPUSH(T,CLAUSE:TAIL[CLAUSES[I]]);
#NEWVAR←#NEWVAR+1;
END;
IF RSIZE(H) THEN
BEGIN
RTRIM(H);
HH←$APPEND($AAPPEND(RSTACK:STACK[H]),MOVECODE);
END
ELSE HH←MOVECODE;
EXPR$:BODY[HH][I←EXPR$:#BODY[HH]] ←5-I; ! retry addr;
IF FAILURE_CLAUSE THEN HH←$APPEND(HH,CLAUSE:TAIL[FAILURE_CLAUSE]);
HH←$APPEND($PUSHPCPCODE,HH);
IF RSIZE(T) THEN
BEGIN
RTRIM(T);
TT←$APPEND($AAPPEND(RSTACK:STACK[T]),$KVARPCODE(#NEWVAR));
END
ELSE TT←$KVARPCODE(#NEWVAR);
IF RSIZE(HR) THEN
BEGIN
RTRIM(HR);
HHR←$APPEND($AAPPEND(RSTACK:STACK[HR]),HH);
END
ELSE HHR←HH;
BEGIN
RPTR(EXPR$)ARRAY TMP[1:6];
TMP[1]←MOVEDEC;
TMP[2]←DESTCOMP;
TMP[3]←HHR;
TMP[4]←TT;
TMP[5]←MOVEKIL;
TMP[6]←$MDONEPCODE;
RETURN($AAPPEND(TMP));
END;
END;
! returns the pointer to the arm affixed to obj;
RPTR(FRAME) PROCEDURE ARM_CHECK(RPTR(FRAME) OBJ);
BEGIN
RPTR(FRAME) TEMP;
TEMP←OBJ;
WHILE TEMP≠F_WRLD DO
IF EQU(FRAME:PNAME[TEMP],"BARM") THEN RETURN(TEMP)
ELSE IF EQU(FRAME:PNAME[TEMP],"YARM") THEN ERROR("YARM cannot be moved")
ELSE TEMP←FRAME:DAD[TEMP];
ERROR(FRAME:PNAME[OBJ]," cannot be moved");
END;
! saves the first part of the instruction for move commands;
PROCEDURE OLDSAV(STRING CMD,OBJ);
BEGIN
OLDCMD←CMD;
OLDOBJ←OBJ;
END;
PROCEDURE MOVEPCODE(RPTR(FRAME) MFRAME;
RPTR(EXPR$) ARRAY FDESTS; INTEGER NFDEST;
REFERENCE RPTR(EXPR$)MOVEDEC,DESTCOMP,MOVECODE,MOVEKIL);
BEGIN
RPTR(SYMBOL) S1,S2; RPTR(FRAME)F1; INTEGER NFDEST0;
S1←CHECK(FRAME:PNAME[MFRAME],#FR);
S2←CHECK(FRAME:PNAME[F1←ARM_CHECK(MFRAME)],#FR);
$TTROFF←$TMPOFF;
NFDEST0←NFDEST+1;
$TMPOFF←$TMPOFF+NFDEST0;
$MOVEPCODE(S1,S2,FDESTS,NFDEST,DESTCOMP,MOVECODE);
MOVEDEC←$SMPDCLPCODE(#TR,NFDEST0);
MOVEKIL←$KVARPCODE(NFDEST0);
END;
INTERNAL PROCEDURE ALONGPROC(STRING AXIS,FRA1);
BEGIN
INTEGER I,INDEX;
RPTR(expr$)SCAL;RPTR(SYMBOL)SYMPTR;RPTR(FRAME)FRAM1;
INTEGER ARRAY BUFF1[1:3],BUFF3[1:5];
RPTR(EXPR$)ARRAY PTR[1:3],DEST[1:1];
SCAL←$$GTANYEXP("distance to be moved along axis",#SC);
SYMPTR←CHECK(AXIS[1 TO 1]&"HAT",#VT);
OLDSAV("MOVE"&AXIS[1 TO 1],FRA1); ! saves for default instructions;
FRAM1←BELONGS(FRA1,#FR);
INDEX←0;
FOR I←XAGTVAL, SYMBOL:INDEX[SYMPTR],SYMBOL:OFFSET[SYMPTR],
XSVMUL, XTVADD DO BUFF3[INDEX←INDEX+1]←I;
SYMPTR←CHECK(FRA1,#FR);
INDEX←0;
IF SYMBOL:INDEX[SYMPTR]>0 THEN
FOR I←XAGTVAL, SYMBOL:INDEX[SYMPTR],SYMBOL:OFFSET[SYMPTR]
DO BUFF1[INDEX←INDEX+1]←I
ELSE FOR I←XGTVAL, SYMBOL:OFFSET[SYMPTR],XNOOP
DO BUFF1[INDEX←INDEX+1]←I;
PTR[1]←αEXPR$(BUFF1,0);
PTR[2]←SCAL;
PTR[3]←αEXPR$(BUFF3,0);
DEST[1]←$AAPPEND(PTR);
BEGIN RPTR(EXPR$)ARRAY M[1:4];
MOVEPCODE(FRAM1,DEST,1,M[1],M[2],M[3],M[4]);
$$PCODE←$AAPPEND(M);
END;
$DISPLAYLIST[#FR]←NULL;
END;
! moves the frame along one axis by a scalar;
INTERNAL PROCEDURE AXMOVPROC;
BEGIN
STRING FRA1,AXIS;
AXIS←TOKEN[5 TO 5];
FRA1←MVFR_READ;
WORD_READ("BY");
ALONGPROC(AXIS,FRA1);
$DISPLAYLIST[#FR]←NULL;
END;
! reads/exec TO <fr>+<vt>{wrt <fr>} or BY <vector>{wrt <fr>};
PROCEDURE PPBYPROC(REFERENCE RPTR(EXPR$)D,C,M,K);
BEGIN
RPTR(EXPR$)ARRAY E[1:4];
RPTR(FRAME) FRAM1;RPTR(EXPR$)ARRAY FDEST[1:1];
! MOVE<fr>BY<vt> ≡ MOVE<fr>TO⊗+<vt>;
TOKEN←OLDOBJ;
#TOKEN←ID_TYPE;
STOKEN←TRUE;
$CLINR←"+"&$CLINR;
FDEST[1]←$$GTANYEXP("destination of MOVE",#FR);
FRAM1←BELONGS (OLDOBJ,#FR);
MOVEPCODE(FRAM1,FDEST,1,D,C,M,K);
$DISPLAYLIST[#FR]←NULL;
E[1]←D;E[2]←C;E[3]←M;E[4]←K;
$$PCODE←$AAPPEND(E);
END;
PROCEDURE PPTOPROC(REFERENCE RPTR(EXPR$)D,C,M,K);
BEGIN
RPTR(FRAME) FRAM1; RPTR(EXPR$) ARRAY FDESTS[1:10]; INTEGER NFDEST;
RPTR(EXPR$)ARRAY E[1:4];
NFDEST←0;
DO BEGIN
FDESTS[NFDEST←NFDEST+1]←$$GTANYEXP("Destination part of MOVE",#FR);
IF NFDEST=10 THEN ERROR("Pointy cannot currently handle more than a 9 segment move");
GTOKEN(FALSE);
END UNTIL TOKEN≠",";
STOKEN←TRUE;
FRAM1←BELONGS (OLDOBJ,#FR);
MOVEPCODE(FRAM1,FDESTS,NFDEST,D,C,M,K);
$DISPLAYLIST[#FR]←NULL;
E[1]←D;E[2]←C;E[3]←M;E[4]←K;
$$PCODE←$AAPPEND(E);
END;
INTERNAL PROCEDURE PBYPROC(REFERENCE RPTR(EXPR$)C,M);
BEGIN RPTR(EXPR$) D,K; PPBYPROC(D,C,M,K); END;
INTERNAL PROCEDURE PTOPROC(REFERENCE RPTR(EXPR$)C,M);
BEGIN RPTR(EXPR$) D,K; PPTOPROC(D,C,M,K); END;
INTERNAL RECURSIVE PROCEDURE MOVEPROC;
BEGIN RPTR(EXPR$)MOVEDEC,DESTCOMP,MOVECODE,MOVEKIL; STRING FR1,AXIS;
FR1←IDF_READ; GTOKEN;
OLDSAV("MOVE",FR1);
IF EQU(TOKEN,"TO") THEN PPTOPROC(MOVEDEC,DESTCOMP,MOVECODE,MOVEKIL)
ELSE IF EQU(TOKEN,"BY") THEN PPBYPROC(MOVEDEC,DESTCOMP,MOVECODE,MOVEKIL)
ELSE ERROR("TO or BY required");
GTOKEN(FALSE);
IF EQU(TOKEN,"ON") OR EQU(TOKEN,"WITH")THEN
BEGIN "on or with"
RPTR(CLAUSE)ARRAY CLAUSES[1:15]; INTEGER #CLAUSES;
INTEGER BITS,TMPOFF;
TMPOFF←$TMPOFF; #CLAUSES←0;
IF EQU(FR1,"BARM") THEN BITS←'4 ELSE IF
EQU(FR1,"YARM") THEN BITS←1 ELSE
ERROR("For force sensing can only use barm or yarm in move");
WHILE EQU(TOKEN,"ON") OR EQU(TOKEN,"WITH") DO
BEGIN RPTR(CLAUSE)C; C←NEW_RECORD(CLAUSE);
IF EQU(TOKEN,"ON")
THEN CMONPROC(C,BITS)
ELSE WITHPROC(C);
CLAUSES[#CLAUSES←#CLAUSES+1]←C;
END;
$$PCODE←FULLMOVE(CLAUSES, #CLAUSES,MOVEDEC,DESTCOMP,MOVECODE,MOVEKIL);
$TMPOFF←TMPOFF;
END "on or with";
STOKEN←TRUE;
END;
INTERNAL PROCEDURE PARKINGPROC;
BEGIN
STRING PAR;
GTOKEN(FALSE);
IF FINAL THEN ASKUSER("MOVE BARM TO BPARK; {MOVE YARM TO YPARK}")
ELSE IF EQU(TOKEN,"BARM") THEN ASKUSER("MOVE BARM TO BPARK")
ELSE IF EQU(TOKEN,"YARM") THEN ASKUSER("MOVE YARM TO YPARK")
ELSE ERROR("can only park BARM or YARM");
$$PCODE←PARSE;
END;
! drivecode,opclcode,jtmove,driveproc;
! drives the indicated joint of the arm (what): movement is absolute
if how=to, differential if how=by;
PROCEDURE DRIVECODE(STRING WHAT,HOW;INTEGER JOINT;RPTR(EXPR$)SCAL);
$$PCODE←$DRIVEPCODE((IF EQU(WHAT,"BJT") THEN BLUE
ELSE YELLOW),HOW,JOINT,SCAL);
! executes close or open instruction. How determines if the movement is
absolute (to) or differential (by), op indicates the operation(open/close);
INTERNAL PROCEDURE OPCLCODE(STRING OP,HAND,HOW;RPTR(EXPR$)SCAL);
BEGIN
IF EQU(HAND,"BHAND")
THEN IF EQU(HOW,"TO") OR EQU(OP,"OPEN")
THEN DRIVECODE("BJT",HOW,7,SCAL)
ELSE DRIVECODE("BJT",HOW,7,$APPEND(SCAL,EXPR$1(XSNEG),#SC))
ELSE PRINT(#NOTYET);
$DISPLAYLIST[#SC]←NULL;
END;
! parses the instruction
DRIVE BJT|YJT (#) TO|BY <scalar>;
INTERNAL PROCEDURE JTMOVE(STRING WHAT,HOW;INTEGER JOINT);
BEGIN "J"
RPTR(EXPR$) SCAL;
SCAL←$$GTANYEXP("joint movement angle",#SC);
OLDSAV("DRIVE",CVS(JOINT)); ! saves for default instructions;
IF EQU(WHAT,"BJT") THEN
DRIVECODE(WHAT,HOW,JOINT,SCAL)
ELSE PRINT(#NOTYET);
$DISPLAYLIST[#FR]←NULL;
END "J";
INTERNAL PROCEDURE DRIVEPROC;
BEGIN
STRING HOW;
STRING WHAT;INTEGER JOINT;
WHAT←IDF_READ;
IF EQU(WHAT,"BJT") OR EQU(WHAT,"YJT")
THEN BEGIN
WORD_READ("("); ! reads "(number)";
GTOKEN;
JOINT←INTSCAN(TOKEN,$BRCHR);
IF JOINT<1 OR JOINT>7
THEN ERROR("non existent joint: ",cvs(joint));
WORD_READ(")");
HOW←IDF_READ;
IF EQU(HOW,"BY") OR EQU(HOW,"TO")
THEN JTMOVE(WHAT,HOW,JOINT)
ELSE ERROR("TO or BY required");
END
ELSE ERROR("BJT or YJT required");
$DISPLAYLIST[#FR]←NULL;
END;
! centerproc,stopproc,retryproc;
INTERNAL PROCEDURE CENTERPROC;
BEGIN "PCENTER"
STRING POS;
POS←ARM_READ; ! if the arm is not indicated BARM is assumed;
IF EQU(POS,"BARM")
THEN $$PCODE←$CENTERPCODE(BLUE)
ELSE PRINT(#NOTYET);
END "PCENTER";
INTERNAL PROCEDURE STOPPROC;
BEGIN "STOPPROC"
STRING POS;
POS←ARM_READ;
IF EQU(POS,"BARM")
THEN $$PCODE←$STOPPCODE(BARM_MECH)
ELSE PRINT(#NOTYET);
END "STOPPROC";
INTERNAL PROCEDURE RETRYPROC;
BEGIN "RETRYPROC"
IF NOT $ERRCMON THEN ERROR("RETRY: only valid inside an ERROR condition monitor");
IF ($ERRLEVEL≠$LEVEL) AND ($ERRLEVEL+1≠$LEVEL) THEN
ERROR("RETRY: must be the same lexical level as the block of theerror condition");
$$PCODE←$PRETRYPCODE;
END "RETRYPROC";
! opening, opclproc,closeproc;
INTERNAL PROCEDURE OPENING(STRING FIRST,WHAT,HOW);
BEGIN
RPTR(EXPR$)SCAL;
SCAL←$$GTANYEXP("hand opening or closing",#SC);
OLDSAV(FIRST,WHAT); ! saves for default instructions;
OPCLCODE(FIRST,WHAT,HOW,SCAL);
END;
! parses the instructions
OPEN <hand> TO|BY <scalar>;
! CLOSE <hand> TO|BY <scalar>;
INTERNAL PROCEDURE OPCLPROC(STRING FIRST);
BEGIN
STRING WHAT;
WHAT←HAND_READ;
GTOKEN;
IF EQU(TOKEN,"TO") OR EQU(TOKEN,"BY")
THEN OPENING(FIRST,WHAT,TOKEN)
ELSE ERROR("Need a TO or BY for OPEN/CLOSE statement");
END;
! parses the instructions
CLOSE <hand> TO|BY <scalar> (BHAND as default);
INTERNAL PROCEDURE CLOSEPROC;
BEGIN
STRING HAND,HOW;
GTOKEN;
IF EQU(HAND←TOKEN,"BHAND") OR EQU(TOKEN,"YHAND")
THEN GTOKEN
ELSE HAND←"BHAND";
IF EQU(HOW←TOKEN,"BY") OR EQU(TOKEN,"TO")
THEN OPENING("CLOSE",HAND,HOW)
ELSE ERROR("CLOSE: need hand opening TO or BY");
END;
! onproc;
INTERNAL PROCEDURE ONPROC(RPTR(EXPR$)E(NULL_RECORD));
IFC FALSE THENC
BEGIN
! IF $COMPILE=0 THEN ERROR("ON must be inside a procedure");
$COMPILE←$COMPILE+1;
GTOKEN;
IF EQU(TOKEN,"FORCE") THEN FORCECM(E,0)
ELSE IF EQU(TOKEN,"TORQUE") THEN FORCECM(E,'3000)
ELSE ERROR("ON: only FORCE or TORQUE available");
$COMPILE←$COMPILE-1;
END;
ENDC;
END "PPROC2";